#include "../globals.h"

using namespace std;

void printUsage()
{
	cout << "Commandline argument for server:" << endl;
	cout << "-hn <server_hostname>" << endl;
	cout << "-pn <server_portnumber>" << endl;
	cout << "-f <filename>" << endl;
	cout << "-pl_ack <P_l for ack packet>" << endl;
	cout << "-pc_ack <P_c for ack packet>" << endl;
	cout << "-pl_data <P_l for data packet>" << endl;
	cout << "-pc_data <P_c for data packet>" << endl;
}

char* server_hostname = 0;
int server_portnum = 0;
char* filename = 0;
double pl_ack = 0;
double pc_ack = 0;
double pl_data = 0;
double pc_data = 0;
bool done = false;

int main(int argc, char **argv)
{
	if (argc != 15)
	{
		printUsage();
		exit(1);
	}
	
	for (int i = 1; i < argc; i++)
	{
		if (strcmp(argv[i], "-hn") == 0)
		{
			i++;
			server_hostname = argv[i];
		}
		if (strcmp(argv[i], "-pn") == 0)
		{
			i++;
			server_portnum = atoi(argv[i]);
		}
		else if (strcmp(argv[i], "-f") == 0)
		{
			i++;
			filename = argv[i];
		}
		else if (strcmp(argv[i], "-pl_ack") == 0)
		{
			i++;
			pl_ack = atof(argv[i]);
		}
		else if (strcmp(argv[i], "-pc_ack") == 0)
		{
			i++;
			pc_ack = atof(argv[i]);
		}
		else if (strcmp(argv[i], "-pl_data") == 0)
		{
			i++;
			pl_data = atof(argv[i]);
		}
		else if (strcmp(argv[i], "-pc_data") == 0)
		{
			i++;
			pc_data = atof(argv[i]);
		}
	}
	
	// get directory of client
	string clientDirectory = argv[0];
	clientDirectory = clientDirectory.substr(0,clientDirectory.find_last_of("\\/") + 1);
	
	client = new CClient(clientDirectory, server_hostname, server_portnum, filename, 
					pl_ack, pc_ack, pl_data, pc_data);
	
	client->pendingsend().type = FILE_REQUEST;
	strcpy(client->pendingsend().payload, filename);
	client->pendingsend().length = strlen(filename);
	
	if ( client->sendpacket() != -1 )
	{
		if ( (client->recvpacket()) != -1 )
		{
			if ( client->lastrecv().type == ERROR )
			{
				// error sent back from server, print error
				
				// following done so we can treat client->lastrecv().payload as cstring
				client->lastrecv().payload[client->lastrecv().length] = '\0'; // THIS IS BAD, WE ASSUME BUFFER NOT FULL!!
				cout << "Error: " << client->lastrecv().payload << endl;
			}
			else if (client->lastrecv().type == DATA )
			{
				int ret = 0;
				// valid data sent by server, create requested file and send ACK
				string filepath = clientDirectory + filename;
				ofstream newfile(filepath.c_str());
				
				if (newfile.is_open())
				{
					do
					{
						if ( client->lastrecv().type == TRANSFER_COMPLETE )
						{
							// done
							done = true;
						}
						else
						{
							if ( client->isLastPacketValid() )
							{
								// more data received in sequence
								newfile.write(client->lastrecv().payload, client->lastrecv().length);
							}
				
							client->pendingsend().type = ACK;
							client->pendingsend().length = 0;
							if ( client->sendpacket() == -1 )
							{
								perror("error: sendto() failed\n");
							}
						}
					} while ( !done && (ret = client->recvpacket()) >= 0 );
					
					newfile.close();
					client->transferComplete();
				}
				else
				{
					perror("error: failed to create new file\n");
					exit(3);
				}
			}
		}
	}
	else
	{
		perror("error: sendto() failed\n");
	}
	
	exit(0);
}
		
